package org.batatasframework.support;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.springframework.util.Assert;

import cn.bonoon.kernel.util.StringHelper;

public class CatalogDefinitionMapped<T extends AbstractSupportDefinition>{
	private final static String DEFAULT_CATALOG = "DEFAULT_CATALOG_NAME";
	
	private final Map<String, InternalCatalogDefinitionCollection> catalogMapped = new HashMap<>();

	private String _getKey(String key){
		return StringHelper.get(key, DEFAULT_CATALOG);
	}
	
	/** 不创建新对象，如果需要创建新对象的，请使用{@link #get(String)} */
	public CatalogDefinitionCollection<T> find(String catalog){
		return __internalFind(catalog);
	}
	
	public T find(String catalog, String key){
		InternalCatalogDefinitionCollection catalogCollection = __internalFind(catalog);
		if(null != catalogCollection) return catalogCollection.get(key);
		return null;
	}
	
	private InternalCatalogDefinitionCollection __internalFind(String catalog){
		return catalogMapped.get(_getKey(catalog));
	}
	
	public CatalogDefinitionCollection<T> notNull(String catalog, String message){
		InternalCatalogDefinitionCollection catalogCollection = __internalFind(catalog);
		Assert.notNull(catalogCollection, message);
		return catalogCollection;
	}
	
	public T notNull(String catalog, String key, String message){
		return notNull(catalog, message).notNull(key, message);
	}

	/** 如果不存在该类型，会创建一个新的对象；如果不需要创建新对象的，请使用{@link #find(String)} */
	private CatalogDefinitionCollection<T> __internalGetOrCreate(String catalog){
		InternalCatalogDefinitionCollection crc = __internalFind(catalog);
		if(null == crc){
			String key = _getKey(catalog);
			crc = new InternalCatalogDefinitionCollection(key);
			catalogMapped.put(key, crc);
		}
		return crc;
	}
	
	public void put(String catalog, String key, T definition){
		__internalGetOrCreate(catalog).put(key, definition);
	}
	
	public Iterable<T> iterable(String catalog){
		InternalCatalogDefinitionCollection crc = __internalFind(catalog);
		if(null == crc) return Collections.emptyList();
		return crc;
	}

	public void finish() {
		for(InternalCatalogDefinitionCollection icdc : catalogMapped.values()){
			icdc.finish();
		}
	}
	
	private class InternalCatalogDefinitionCollection implements CatalogDefinitionCollection<T>, Iterable<T>{

		protected final String catalog;
		protected final Map<String, T> definitionMapped = new HashMap<>();
		//  对定义进行排序处理
		private final List<T> items = new ArrayList<>();

		protected InternalCatalogDefinitionCollection(String catalog){
			this.catalog = catalog;
		}
		
		@Override
		public Iterator<T> iterator() {
			return items.iterator();
		}
		
		public String getCatalog() {
			return catalog;
		}

		public void put(String key, T definition){
			Assert.isNull(definitionMapped.put(key, definition), "已经存在相同的定义[" + key + "]！");
		}
		
		public T get(String key){
			return definitionMapped.get(key);
		}
		
		public T notNull(String key, String message){
			T definition = get(key);
			Assert.notNull(definition, message);
			return definition;
		}

		public void finish() {
			items.addAll(definitionMapped.values());
			//排序处理
			Collections.sort(items);
			
			for(T definition : items){
				definition.finish();
			}
			
		}
	}
}
